package com.mm.cloud.common.mq.config;

import com.mm.cloud.common.mq.enums.ExchangeEnum;
import com.mm.cloud.common.mq.enums.QueueEnum;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 队列配置
 *
 * @author mr
 * @since 2021-06-30
 */
@Configuration
public class QueueConfig {

    @Autowired
    private DirectExchange directExchange;

    @Autowired
    private TopicExchange topicExchange;

    @Autowired
    private FanoutExchange fanoutExchange;

    @Autowired
    private ConfigurableBeanFactory configurableBeanFactory;

    @Bean
    public QueueFactory queueFactory() {
        QueueFactory result = new QueueFactory() {
            @Override
            public void found() {
                QueueEnum[] queues = QueueEnum.values();
                for (int i = 0; i < queues.length; i++) {
                    binding("binding" + i, ofQueue(queues[i]), ofExchange(queues[i].getRouting().getExchange()), queues[i].getRouting().getKey());
                }
            }
        };
        result.found();
        return result;
    }

    /**
     * 得到交换机
     *
     * @param ee
     * @return 交换机
     */
    private Exchange ofExchange(ExchangeEnum ee) {
        switch (ee) {
            case DIRECT:
                return directExchange;
            case FANOUT:
                return fanoutExchange;
            case TOPIC:
                return topicExchange;
            default:
                throw new RuntimeException("of exchange type not exists");
        }
    }

    /**
     * 得到队列
     *
     * @param qe
     * @return 队列
     */
    private Queue ofQueue(QueueEnum qe) {
        Queue result = new Queue(qe.getKey());
        configurableBeanFactory.registerSingleton(qe.getName(), result);
        return result;
    }

    /**
     * 绑定队列
     *
     * @param bindingName
     * @param queue
     * @param exchange
     * @param routingKey
     */
    private void binding(String bindingName, Queue queue, Exchange exchange, String routingKey) {
        configurableBeanFactory.registerSingleton(bindingName, BindingBuilder.bind(queue).to(exchange).with(routingKey).noargs());
    }

    /**
     * 定义一个创建队列工厂内部类，只用于创建队列
     */
    public interface QueueFactory {
        void found();
    }
}
